

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
  
public class RSAUtils {  
    private static String pubKey ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVRiDkEKXy/KBTe+UmkA+feq1zGWIgBxkgbz7aBJGb5+eMKKoiDRoEHzlGndwFKm4mQWNftuMOfNcogzYpGKSEfC7sqfBPDHsGPZixMWzL3J10zkMTWo6MDIXKKqMG1Pgeq1wENfJjcYSU/enYSZkg3rFTOaBSFId+rrPjPo7Y4wIDAQAB";
    private static String priKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJVGIOQQpfL8oFN75SaQD596rXMZYiAHGSBvPtoEkZvn54woqiINGgQfOUad3AUqbiZBY1+24w581yiDNikYpIR8Luyp8E8MewY9mLExbMvcnXTOQxNajowMhcoqowbU+B6rXAQ18mNxhJT96dhJmSDesVM5oFIUh36us+M+jtjjAgMBAAECgYABtnxKIabF0wBD9Pf8KUsEmXPEDlaB55LyPFSMS+Ef2NlfUlgha+UQhwsxND6CEKqS5c0uG/se/2+4l0jXz+CTYBEh+USYB3gxcMKEo5XDFOGaM2Ncbc7FAKJIkYYN2DHmr4voSM5YkVibw5Lerw0kKdYyr0Xd0kmqTok3JLiLgQJBAOGZ1ao9oqWUzCKnpuTmXre8pZLmpWPhm6S1FU0vHjI0pZh/jusc8UXSRPnx1gLsgXq0ux30j968x/DmkESwxX8CQQCpY1+2p1aX2EzYO3UoTbBUTg7lCsopVNVf41xriek7XF1YyXOwEOSokp2SDQcRoKJ2PyPc2FJ/f54pigdsW0adAkAM8JTnydc9ZhZ7WmBhOrFuGnzoux/7ZaJWxSguoCg8OvbQk2hwJd3U4mWgbHWY/1XB4wHkivWBkhRpxd+6gOUjAkBH9qscS52zZzbGiwQsOk1Wk88qKdpXku4QDeUe3vmSuZwC85tNyu+KWrfM6/H74DYFbK/MzK7H8iz80uJye5jVAkAEqEB/LwlpXljFAxTID/SLZBb+bCIoV/kvg+2145F+CSSUjEWRhG/+OH0cQfqomfg36WrvHl0g/Xw06fg31HgK";

    public static void main(String[] args) throws Exception {  
        // TODO Auto-generated method stub  
//        HashMap<String, Object> map = RSAUtils.getKeys();  
//        //生成公钥和私钥  
//        RSAPublicKey publicKey = (RSAPublicKey) map.get("public");  
//        RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");  
//          
//        //模  
//        String modulus = publicKey.getModulus().toString();  
//        //公钥指数  
//        String public_exponent = publicKey.getPublicExponent().toString();  
//        //私钥指数  
//        String private_exponent = privateKey.getPrivateExponent().toString();  
        //明文  
        String ming = "18668078971";  
        //使用模和指数生成公钥和私钥  
//        RSAPublicKey pubKey = RSAUtils.getPublicKey(modulus, public_exponent);  
//        RSAPrivateKey priKey = RSAUtils.getPrivateKey(modulus, private_exponent);  
 //       RSAUtils.init(pubKey, priKey);
        //加密后的密文  
    /*    String mi = RSAUtils.encryptByPublicKey(ming, RSAUtils.getPubKey(pubKey));  
        System.err.println(mi);  
        //解密后的明文  
        ming = RSAUtils.decryptByPrivateKey(mi, RSAUtils.getPrivateKey(priKey));  
        System.err.println(ming);  */
        
        
       /* byte[] jiami = RSAUtils.encryptByPublicKey("14706407735", pubKey);
        System.out.println("rsa:===="+jiami);
        String jiami64 = URLEncoder.encode(RSAUtils.encryptBASE64(jiami),"UTF-8");
        System.out.println("ttttt:===="+jiami64);*/

        String param = "186680789711";
        //byte[] jiemi64 = RSAUtils.decryptBASE64(URLDecoder.decode("cflCAo9SuhS3G9y2VLN%2F3fxrqYAwJpeveaYq9QriRc%2B9RfA70cwhpfE8g%2Bowj8SngN4KMjc9i3kj%0D%0AYYqPJfGtxwIKlkBY0LNZuPwJSM0cBdayRcVfpmJ%2Fmxe6EGtRer4%2FhWsWaFzRt2OgH3mcoyw9fJnS%0D%0A3O3cffxntqDfm%2BoEsBk%3D%0D%0A", "UTF-8"));
        //System.out.println("base64解密后：" + jiemi64);
        String a = test(param);
        System.out.println("加密前：" + a);
        String jiemi = RSAUtils.decryptByPrivateKey(a.getBytes(), priKey);
        System.out.println("解密后：" + jiemi);
    }
	
    public static String test(String param) throws Exception {
		byte[] s = RSAUtils.encryptByPublicKey(param, pubKey);
		String ss = RSAUtils.encryptBASE64(s);
		return ss;
	}

	
//	public static void init(String pubkey,String prikey)
//	{
//		pubKey = pubkey;
//		priKey = prikey;
//	}
//    /** 
//     * 生成公钥和私钥 
//     * @throws NoSuchAlgorithmException  
//     * 
//     */  
//    public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException{  
//        HashMap<String, Object> map = new HashMap<String, Object>();  
//        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
//        keyPairGen.initialize(1024);  
//        KeyPair keyPair = keyPairGen.generateKeyPair();  
//        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
//        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
//        map.put("public", publicKey);  
//        map.put("private", privateKey);  
//        return map;  
//    }  
    /**
     * 实例化私钥
     * 
     * @return
     */
    public static RSAPrivateKey getPrivateKey( String priKey) {
     PrivateKey privateKey = null;
     PKCS8EncodedKeySpec priPKCS8;
     try {
      priPKCS8 = new PKCS8EncodedKeySpec(
        new BASE64Decoder().decodeBuffer(priKey));
      KeyFactory keyf = KeyFactory.getInstance("RSA");
      privateKey = keyf.generatePrivate(priPKCS8);
     } catch (IOException e) {
      e.printStackTrace();
     } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
     } catch (InvalidKeySpecException e) {
      e.printStackTrace();
     }
     return (RSAPrivateKey)privateKey;
    }
    /**
     * 实例化公钥
     * 
     * @return
     */
    public  static RSAPublicKey getPubKey(String pubKey) {
     PublicKey publicKey = null;
     try {
      // 自己的公钥(测试)
         java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
        new BASE64Decoder().decodeBuffer(pubKey));
      // RSA对称加密算法
      java.security.KeyFactory keyFactory;
      keyFactory = java.security.KeyFactory.getInstance("RSA");
      // 取公钥匙对象
      publicKey = keyFactory.generatePublic(bobPubKeySpec);
     } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
     } catch (InvalidKeySpecException e) {
      e.printStackTrace();
     } catch (IOException e) {
      e.printStackTrace();
     }
     return (RSAPublicKey)publicKey;
    }
    
//    /** 
//     * 使用模和指数生成RSA公钥 
//     * 注意：【此代码用了默认补位方式，为RSA/None/PKCS1Padding，不同JDK默认的补位方式可能不同，如Android默认是RSA 
//     * /None/NoPadding】 
//     *  
//     * @param modulus 
//     *            模 
//     * @param exponent 
//     *            指数 
//     * @return 
//     */  
//    public static RSAPublicKey getPublicKey(String modulus, String exponent) {  
//        try {  
//            BigInteger b1 = new BigInteger(modulus);  
//            BigInteger b2 = new BigInteger(exponent);  
//            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
//            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);  
//            return (RSAPublicKey) keyFactory.generatePublic(keySpec);  
//        } catch (Exception e) {  
//            e.printStackTrace();  
//            return null;  
//        }  
//    }  
//  
//    /** 
//     * 使用模和指数生成RSA私钥 
//     * 注意：【此代码用了默认补位方式，为RSA/None/PKCS1Padding，不同JDK默认的补位方式可能不同，如Android默认是RSA 
//     * /None/NoPadding】 
//     *  
//     * @param modulus 
//     *            模 
//     * @param exponent 
//     *            指数 
//     * @return 
//     */  
//    public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {  
//        try {  
//            BigInteger b1 = new BigInteger(modulus);  
//            BigInteger b2 = new BigInteger(exponent);  
//            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
//            RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);  
//            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
//        } catch (Exception e) {  
//            e.printStackTrace();  
//            return null;  
//        }  
//    }  
  
    /** 
     * 公钥加密 
     *  
     * @param data 
     * @param publicKey 
     * @return 
     * @throws Exception 
     */  
    public static String encryptByPublicKey(String data, RSAPublicKey publicKey)  
            throws Exception {  
        Cipher cipher = Cipher.getInstance("RSA");  
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
        // 模长  
        int key_len = publicKey.getModulus().bitLength() / 8;  
        // 加密数据长度 <= 模长-11  
        String[] datas = splitString(data, key_len - 11);  
        String mi = "";  
        //如果明文长度大于模长-11则要分组加密  
        for (String s : datas) {  
            mi += bcd2Str(cipher.doFinal(s.getBytes()));  
        }  
        return mi;  
    }  
  
    /** 
     * 私钥解密 
     *  
     * @param data 
     * @param privateKey 
     * @return 
     * @throws Exception 
     */  
    public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey)  
            throws Exception {  
        Cipher cipher = Cipher.getInstance("RSA");  
        cipher.init(Cipher.DECRYPT_MODE, privateKey);  
        //模长  
        int key_len = privateKey.getModulus().bitLength() / 8;  
        byte[] bytes = data.getBytes();  
        byte[] bcd = ASCII_To_BCD(bytes, bytes.length);  
//        System.err.println(bcd.length);  
        //如果密文长度大于模长则要分组解密  
        String ming = "";  
        byte[][] arrays = splitArray(bcd, key_len);  
        for(byte[] arr : arrays){  
            ming += new String(cipher.doFinal(arr));  
        }  
        return ming;  
    }  
    /** 
     * ASCII码转BCD码 
     *  
     */  
    public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {  
        byte[] bcd = new byte[asc_len / 2];  
        int j = 0;  
        for (int i = 0; i < (asc_len + 1) / 2; i++) {  
            bcd[i] = asc_to_bcd(ascii[j++]);  
            bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4));  
        }  
        return bcd;  
    }  
    public static byte asc_to_bcd(byte asc) {  
        byte bcd;  
  
        if ((asc >= '0') && (asc <= '9'))  
            bcd = (byte) (asc - '0');  
        else if ((asc >= 'A') && (asc <= 'F'))  
            bcd = (byte) (asc - 'A' + 10);  
        else if ((asc >= 'a') && (asc <= 'f'))  
            bcd = (byte) (asc - 'a' + 10);  
        else  
            bcd = (byte) (asc - 48);  
        return bcd;  
    }  
    /** 
     * BCD转字符串 
     */  
    public static String bcd2Str(byte[] bytes) {  
        char temp[] = new char[bytes.length * 2], val;  
  
        for (int i = 0; i < bytes.length; i++) {  
            val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);  
            temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');  
  
            val = (char) (bytes[i] & 0x0f);  
            temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');  
        }  
        return new String(temp);  
    }  
    /** 
     * 拆分字符串 
     */  
    public static String[] splitString(String string, int len) {  
        int x = string.length() / len;  
        int y = string.length() % len;  
        int z = 0;  
        if (y != 0) {  
            z = 1;  
        }  
        String[] strings = new String[x + z];  
        String str = "";  
        for (int i=0; i<x+z; i++) {  
            if (i==x+z-1 && y!=0) {  
                str = string.substring(i*len, i*len+y);  
            }else{  
                str = string.substring(i*len, i*len+len);  
            }  
            strings[i] = str;  
        }  
        return strings;  
    }  
    /** 
     *拆分数组  
     */  
    public static byte[][] splitArray(byte[] data,int len){  
        int x = data.length / len;  
        int y = data.length % len;  
        int z = 0;  
        if(y!=0){  
            z = 1;  
        }  
        byte[][] arrays = new byte[x+z][];  
        byte[] arr;  
        for(int i=0; i<x+z; i++){  
            arr = new byte[len];  
            if(i==x+z-1 && y!=0){  
                System.arraycopy(data, i*len, arr, 0, y);  
            }else{  
                System.arraycopy(data, i*len, arr, 0, len);  
            }  
            arrays[i] = arr;  
        }  
        return arrays;  
    }  
    
    
    
    
    
    

/**
* 加密<br>
* 用公钥加密
* 
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(String datas, String key)
	throws Exception {
	//要加密的内容
	byte[] data =datas.getBytes("UTF-8");
	// 对公钥解密
	byte[] keyBytes = decryptBASE64(key);

	// 取得公钥
	X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
	KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	Key publicKey = keyFactory.generatePublic(x509KeySpec);

	// 对数据加密;
	Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
	cipher.init(Cipher.ENCRYPT_MODE, publicKey);

	return cipher.doFinal(data);
}


/**
* BASE64加密
* 
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[] key) throws Exception {
	return (new BASE64Encoder()).encodeBuffer(key);
}


//UTF-8编码
//URLEncoder.encode("待编码字符串","UTF-8");


//UTF-8解码
//URLDecoder.decode("待解密字符串", "UTF-8")


/**
 * BASE64解密
 * 
 * @param key
 * @return
 * @throws Exception
 */
public static byte[] decryptBASE64(String key) throws Exception {
	return (new BASE64Decoder()).decodeBuffer(key);
}



/**
 * 解密 用私钥解密
 * 
 * @param data
 * @param key
 * @return
 * @throws Exception
 */
public static String decryptByPrivateKey(byte[] data, String key)
		throws Exception {
	// 对密钥解密
	byte[] keyBytes = decryptBASE64(key);

	// 取得私钥
	PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
	KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

	// 对数据解密
	Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
	cipher.init(Cipher.DECRYPT_MODE, privateKey);

	return new String(cipher.doFinal(data),"UTF-8");
}

//解密手机号
	public static String getMobile(String param,String key) throws Exception{
	param = URLEncoder.encode(param,"UTF-8");
	//先用URL解码，再用base64解码，最后用RAS解码
	byte[] jiemi64 = RSAUtils.decryptBASE64(URLDecoder.decode(param, "UTF-8"));

    return  RSAUtils.decryptByPrivateKey(jiemi64, key);
	}








}
